package djl;

import java.awt.geom.Point2D;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import robocode.HitRobotEvent;

/**
 * A robot that will attempt to destroy as many sample robots possible.
 * 
 * @author David Joel Lazaro
 * @version 1.1
 */

public class DaBeast extends Robot {

  /**
   * run: Moves the robot.
   */
  public void run() {
    // Gets the total width and height of the field
    double width = getBattleFieldWidth();
    double height = getBattleFieldHeight();
    while (true) {
      // Goes to the upper left corner
      goToCorner(getWidth() / 2, height - getHeight() / 2);
      // Goes to the lower right corner
      goToCorner(width - getWidth() / 2, getHeight() / 2);
      // Goes to the upper right corner
      goToCorner(width - getWidth() / 2, height - getHeight() / 2);
      // Goes to the lower left corner
      goToCorner(getWidth() / 2, getHeight() / 2);
    }
  }

  /**
   * Uses the function absoluteBearing to go to a specific point in the field.
   * 
   * @param x The x coordinate.
   * @param y The y coordinate.
   */
  public void goToCorner(double x, double y) {
    double corner = absoluteBearing(getX(), getY(), x, y);
    turnRight(corner - getHeading());
    ahead(Point2D.distance(getX(), getY(), x, y));
  }

  /**
   * onScannedRobot: Fires hard at the enemy.
   * 
   * @param e event
   */
  public void onScannedRobot(ScannedRobotEvent e) {
    fire(2);
  }

  /**
   * onHitRobot: Borrowed from RamFire. Turn to face the robot, then fire hard!
   * 
   * @param e event
   */
  public void onHitRobot(HitRobotEvent e) {
    turnRight(e.getBearing());
    fire(3);
  }

  /**
   * This code was taken from Mark Whitley's website.
   * http://www.codepoet.org/~markw/weber/java/robocode/lesson4.html
   * 
   * @param x1 Absolute x1.
   * @param y1 Absolute y1.
   * @param x2 Absolute x2.
   * @param y2 Absolute y2.
   * @return bearing
   */
  // computes the absolute bearing between two points
  double absoluteBearing(double x1, double y1, double x2, double y2) {
    double xo = x2 - x1;
    double yo = y2 - y1;
    double hyp = Point2D.distance(x1, y1, x2, y2);
    double arcSin = Math.toDegrees(Math.asin(xo / hyp));
    double bearing = 0;

    // both pos: lower-Left
    if (xo > 0 && yo > 0) {
      bearing = arcSin;
    }
    // x neg, y pos: lower-right
    else if (xo < 0 && yo > 0) {
      // arcsin is negative here, actuall 360 - ang
      bearing = 360 + arcSin;
    }
    // x pos, y neg: upper-left
    else if (xo > 0 && yo < 0) {
      bearing = 180 - arcSin;
    }
    // both neg: upper-right
    else if (xo < 0 && yo < 0) {
      // arcsin is negative here, actually 180 + ang
      bearing = 180 - arcSin;
    }

    return bearing;
  }
  
}
